using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;

namespace TimeWar
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public abstract class AI_PlayableObject : VectorShape
    {
        protected Game gameObj = null;
        protected float velocity = 1;
        protected ObjectTypes objectType = ObjectTypes.Inanimate;
        protected bool chased = false;
        protected PlayerIndex player;
        protected int spanOfVibration = 500;
        protected float leftVibe = 1f;
        protected float rightVibe = 1f;
        protected Screen screen = null;

        #region General_Gameplay_Attributes
        protected int energyPoints = 0;

        #endregion General_Gameplay_Attributes

        #region Combat_Related_Attributes
        protected int hitPoints = 100;
        protected int shieldPoints = 0;
        protected List<Weaponry> weapons = null;
        protected int currWeaponIndex = 0;

        #endregion Combat_Related_Attributes

        protected Cue currCue;

        public AI_PlayableObject(Game game, String modelLocn, Screen currScreen, ShapeTypes typeOfShape)
            : base(game, typeOfShape)
        {
            // TODO: Construct any child components here
            gameObj = game;
            ModelLocation = modelLocn;
            Scale = 0.025f;
            Initialize();
            weapons = new List<Weaponry>();
            //weapons.Add(position);
            screen = currScreen;
        }

        protected void loadShipWithWeapons()
        {
            Projectiles bullets = new Projectiles(gameObj);

        }


        public Vector3 Position3D
        {
            get
            {
                return Position;
            }
            set
            {
                Position = value;
            }
        }

        public Vector3 Camera
        {
            set
            {
                CameraPosition = value;
            }
        }

        public bool Chased
        {
            get
            {
                return chased;
            }
            set
            {
                chased = value;
            }
        }

        public PlayerIndex Player
        {
            get
            {
                return player;
            }
            set
            {
                player = value;
            }
        }

        public int SpanOfVibration
        {
            set
            {
                spanOfVibration = value;
            }
        }

        public float LeftVibe
        {
            set
            {
                leftVibe = value;
            }
        }

        public float RightVibe
        {
            set
            {
                rightVibe = value;
            }
        }

        public ObjectTypes ObjectType
        {
            get
            {
                return objectType;
            }
            set
            {
                objectType = value;
            }
        }

        public Vector3 getWeaponPosition()
        {
            //set to ship position for simplicity
            return position;
        }


        public override void Render()
        {
            base.Draw();
            //base.Render();
        }


        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(TimeSpan time, TimeSpan elapsedTime)
        {
            if (true == chased)
            {
                processGamePadCommands(elapsedTime);
            }

            base.Update(time, elapsedTime);

            Move(elapsedTime);

            if (weapons != null && weapons.Count > 0)
            {
                foreach (Weaponry munitions in weapons)
                {
                    if (munitions.Ammunition.Count > 0)
                    {
                        foreach (Weapon munition in munitions.Ammunition)
                        {
                            munition.Update(time, elapsedTime);
                        }
                    }
                }
            }

        }

        public override void onCollision()
        {
            XInputHelper.GamePads[player].vibrate(leftVibe, rightVibe);
            for (int i = 0; i < spanOfVibration; i++) ;
            XInputHelper.GamePads[player].vibrate(0, 0);            
        }

        protected void processGamePadCommands(TimeSpan time)
        {

            if (XInputHelper.GamePads[player].State.IsButtonDown(Buttons.LeftStick))
            {
                //velocity *= 1.05f;
                //MoveForwards(velocity);
                accelerate();
            }
            else if (XInputHelper.GamePads[player].State.IsButtonDown(Buttons.RightStick))            
            {
                //velocity *= 0.8f;
                //MoveBackwards(velocity);
                deccelerate();
            }
            else if (XInputHelper.GamePads[player].State.IsButtonUp(Buttons.LeftStick))
            {
                stopAccelerating();
            }
            else if (XInputHelper.GamePads[player].State.IsButtonUp(Buttons.RightStick))
            {
                //stopAccelerating();
            }


            if (XInputHelper.GamePads[player].LeftPressed)
            {
                RollLeft(1);


            }
            else if (XInputHelper.GamePads[player].RightPressed)
            {
                RollRight(1);
            }
            else if (XInputHelper.GamePads[player].UpPressed)
            {
                //PitchDown(1);
            }
            else if (XInputHelper.GamePads[player].DownPressed)
            {
                //PitchUp(1);
            }

            if (XInputHelper.GamePads[player].ThumbStickLeftY < 0)
            {
                //MoveForwards(velocity);
                //PitchDown(1);

            }
            else if (XInputHelper.GamePads[player].ThumbStickLeftY > 0)
            {
                //MoveBackwards(velocity);
                //PitchUp(1);
            }

            ChangeDirection(XInputHelper.GamePads[player].ThumbStickLeftX, XInputHelper.GamePads[player].ThumbStickLeftY);

            if (XInputHelper.GamePads[player].ThumbStickLeftX < 0)
            {
                //StrafeLeft(velocity);
            }
            else if (XInputHelper.GamePads[player].ThumbStickLeftX > 0)
            {
                //StrafeRight(velocity);
            }

            if (XInputHelper.GamePads[player].State.IsButtonDown(Buttons.LeftShoulder))
            {
                RotateLeft(1);
            }
            else if (XInputHelper.GamePads[player].State.IsButtonDown(Buttons.RightShoulder))
            {
                RotateRight(1);
            }

            if (XInputHelper.GamePads[player].State.IsButtonDown(Buttons.LeftTrigger))
            {
                //Cycle between weapons
                currWeaponIndex++;
                if (currWeaponIndex >= weapons.Count)
                {
                    currWeaponIndex = 0;
                }
            }
            else if (XInputHelper.GamePads[player].State.IsButtonDown(Buttons.RightTrigger))
            {
                //Fire current weapon index
                fireWeapon(currWeaponIndex, time);
            }

        }

        protected override void FillBuffer(VertexPositionColor[] data)
        {
            //throw new Exception("The method or operation is not implemented.");

        }

        protected override int NumberOfVectors
        {
            get { return 1; }
        }

        protected abstract void playMotionSound();
        protected abstract void stopMotionSound();

        public override void MoveForwards(float distance)
        {
            base.MoveForwards(distance);
            playMotionSound();
        }

        public override void MoveBackwards(float distance)
        {
            base.MoveBackwards(distance);
            playMotionSound();
        }

        public override void Move(TimeSpan elapsedTime)
        {
            if (accelerationFactor != 0)
            {
                playMotionSound();
            }
            else
            {
                stopMotionSound();
            }
            base.Move(elapsedTime);
        }

        public virtual void fireWeapon(int index, TimeSpan time)
        {
            Weaponry munitions = null;

            if (weapons.Count <= index)
            {
                //munition = new Weapon(gameObj, player, position, direction, direction, time, null, "Models\\mgun_proj");
                munitions = new Weaponry(gameObj);
            }
            else
            {
                munitions = weapons[index];
            }

            //Particles particles = new Particles(gameObj);
            Weapon photonTorp = new Missile(gameObj, player, position, direction, direction, time, "Content\\Models\\mgun_proj");
            photonTorp.Scale = 0.001f;
            //screen.OnscreenWeapons.Add(photonTorp);
            screen.addScreenObject(photonTorp);

            //Projectile bullet = new Projectile(gameObj, player, getWeaponPosition(), Vector3.Multiply(direction, velocity), direction, time, particles);

            //weapons[index].Add();
        }

        public void sustainDamage(int damage)
        {
            hitPoints -= damage;

            explosionSound();

            if (hitPoints < 0)
            {
                //remove model from screen.
            }
        }

        protected abstract void explosionSound();



    }        
    

}